package me.zhengjie.observer.caster;


import me.zhengjie.observer.event.IWcsEvent;
import me.zhengjie.observer.listener.IWcsEventListener;
import me.zhengjie.observer.type.WcsEventType;
import me.zhengjie.observer.resource.EventExecutorResource;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class WcsMulticasterImpl implements WcsMulticaster, ApplicationContextAware {

    private final EventExecutorResource eventExecutorResource;

    public WcsMulticasterImpl(EventExecutorResource eventExecutorResource) {
        this.eventExecutorResource = eventExecutorResource;
    }

    private final HashMap<String, IWcsEventListener> listenerMap = new HashMap<>();

    @Override
    public void addListenter(IWcsEventListener listener) {
        listenerMap.put(listener.getClass().getName(), listener);
    }

    @Override
    public void addListenter(String listenterName,IWcsEventListener listener) {
        listenerMap.put(listenterName, listener);
    }

    @Override
    public void removeListener(String listenterName) {
        listenerMap.remove(listenterName);
    }


    @Override
    public void multicastEvent(IWcsEvent event, WcsEventType eventType) {
        Map<WcsEventType, List<IWcsEventListener>> wcsEventTypeListMap = listenerMap.values()
                .stream()
                .collect(Collectors.groupingBy(
                        IWcsEventListener::getEventType,
                        Collectors.toList()
                ));

        List<IWcsEventListener> listenerList = wcsEventTypeListMap.getOrDefault(eventType, new ArrayList<>());
        listenerList.forEach(a-> eventExecutorResource.getExecutor().execute(()->a.onEvent(event)));

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        String[] listenerNames = applicationContext.getBeanNamesForType(IWcsEventListener.class);
        for (String listenerName : listenerNames) {
            IWcsEventListener listener = (IWcsEventListener) applicationContext.getBean(listenerName);
            listenerMap.put(listenerName, listener);
        }
    }
}
